/******************************************************************************
* 文件名称: irq.h
* 内容摘要: 描述符头文件
* 创建者の: 孔佳伟
* 个人主页: https://gitee.com/thin-wind/jump
* 修改记录: 
******************************************************************************/

#ifndef __DESC_H_
#define __DESC_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <common.h>

// 段属性定义       
#define DA_32        0x4000             // D/B = 1
#define DA_DR        0x90               // 数据，只读
#define DA_DRW       0x92               // 数据，可读/写
#define DA_DRWA      0x93               // 数据，可读/写，已访问
#define DA_C         0x98               // 代码，仅执行
#define DA_CR        0x9A               // 代码，可执行，可读
#define DA_CCO       0x9C               // 代码，一致性段，仅执行
#define DA_CCOR      0x9E               // 代码，一致性段，可执行，可读，已访问
#define DA_LIMIT_4K  0x8000              // G = 1, 颗粒度：4K
#define DA_LDT       0x82               // TYPE : LDT

// 门属性定义
#define DA_CALL_GATE 0x8C               // 32 位调用门
#define DA_TSS 	     0x89	            // 32 位 TSS (可用)

// 段选择符属性定义
#define SA_RPL0      0                  // RPL = 0
#define SA_RPL1      1                  // RPL = 1
#define SA_RPL2      2                  // RPL = 2
#define SA_RPL3      3                  // RPL = 3
#define SA_TIG       0                  // TI = 0, GDT
#define SA_TIL       4                  // TI = 1, LDT

// 段描述符中 DPL 属性定义（段描述符高 32 位的 bit13-bit14 ）
#define DA_DPL0      0x00               // DPL = 0
#define DA_DPL1      0x20               // DPL = 1
#define DA_DPL2      0x40               // DPL = 2
#define DA_DPL3      0x60               // DPL = 3

// 全局段选择符定义
#define GDT_CODE32_INDEX        1
#define GDT_VIDEO_INDEX         2
#define GDT_CODE32_FLAT_INDEX   3
#define GDT_DATA32_FLAT_INDEX   4
#define GDT_TSS_INDEX           5
#define GDT_LDT_INDEX           6

#define GDT_CODE32_SEL          ((GDT_CODE32_INDEX << 3) + SA_RPL0 + SA_TIG)
#define GDT_VIDEO_SEL           ((GDT_VIDEO_INDEX << 3) + SA_RPL0 + SA_TIG)
#define GDT_CODE32_FLAT_SEL     ((GDT_CODE32_FLAT_INDEX << 3) + SA_RPL0 + SA_TIG)
#define GDT_DATA32_FLAT_SEL     ((GDT_DATA32_FLAT_INDEX << 3) + SA_RPL0 + SA_TIG)
#define GDT_TSS_SEL             ((GDT_TSS_INDEX << 3) + SA_RPL0 + SA_TIG)
#define GDT_LDT_SEL             ((GDT_LDT_INDEX << 3) + SA_RPL0 + SA_TIG)

// 局部段选择符定义
#define LDT_VIDEO_INDEX         0
#define LDT_CODE32_INDEX        1
#define LDT_DATA32_INDEX        2

#define	LDT_VIDEO_SEL           ((LDT_VIDEO_INDEX << 3) + SA_TIL + SA_RPL3)
#define	LDT_CODE32_SEL          ((LDT_CODE32_INDEX << 3) + SA_TIL + SA_RPL3)	
#define	LDT_DATA32_SEL          ((LDT_DATA32_INDEX << 3) + SA_TIL + SA_RPL3)	

#pragma  pack(1)                        // 结构体 1 字节对齐

// 段描述符
typedef struct DESC
{
    U16             limit1;             // 段界限 1
    U16             base1;              // 段基址 1
    U08             base2;              // 段基址 2
    U08             attr1;              // 段属性 1
    U08             attr2_limit2;       // 段属性和段界限
    U08             base3;              // 段基址 3
} DESC;

// 门描述符
typedef struct GATE
{
    U16         offset1;                // 偏移量 1
    U16         selector;               // 选择子
    U08         dount;                  // 参数个数
    U08         attr;                   // 属性
    U16         offset2;                // 偏移量 2
} GATE;

// 任务状态段 TSS
typedef struct TSS
{
    U32         previous;               // 上一个任务链接（TSS 选择符）
    U32         esp0;                   // 内核栈顶
    U32         ss0;                    // 内核栈基址
    U32         unused[22];             // 不使用
    U16         reserved;               // 保留
    U16         iomb;                   // I/O 位图基地址
} TSS;


#pragma  pack()

#ifdef __cplusplus
}
#endif

#endif

